<?php

class RegistrationPage extends Page
{
    public function canView($member = null)
    {
        $result = parent::canView($member);

        if ($result && $mem = Member::currentUser()) {
            $whiteList = array("administrators");
            return $mem->inGroups($whiteList);
        }

        return $result;
    }
}

class RegistrationPage_Controller extends Page_Controller
{
    private static $allowed_actions = array(
        "RegistrationForm"
    );

    public function RegistrationForm()
    {
        $username = new TextField("Username", _t("General.USERNAME", "Username"));
        $username->setDescription(_t("RegistrationPage.USERNAME_DESC", "Username length must be 6-18 characters."));

        $password = new PasswordField("Password", _t("General.PASSWORD", "Password"));
        $password->setDescription(_t("RegistrationPage.PASSWORD_DESC", "Password length must be 6-18 characters."));

        // Upload S&P Docs.
        $image = new FileField("SnPUpload", _t("General.UPLOAD_SNP_DOCS", "Upload S&P Documentations"));

        $type = array("jpg", "png", "pdf", "docx", "zip", "rar", "tar", "gz", "tgz", "doc");
        $validator = new Upload_Validator();
        $validator->setAllowedExtensions($type);
        $validator->setAllowedMaxFileSize(array("*" => 1024 * 1024 * 50));
        $image->setFolderName("Uploads/resident_snp");
        $image->setDescription("Max file size: 50MB.<br/>Supported file formats: " . join(", ", $type));
        $image->setValidator($validator);

        $fields = new FieldList
        (
            new LiteralField("", "<strong>* " . _t("General.ALL_FIELDS_ARE_REQUIRED", "All fields are required.") . "</strong><hr/>"),
            $username,
            $password,
            new PasswordField("ConfirmPassword", _t("General.CONFIRM_PASSWORD", "Confirm Password")),
            new EmailField("Email", _t("General.EMAIL", "Email")),
            new TextField("UnitNo", _t("General.UNIT_NUMBER", "Unit Number")),
            new DropdownField
            (
                "AreaName",
                _t("General.AREA_NAME", "Area Name"),
                array(
                    "A1" => "Area 1",
                    "A2" => "Area 2",
                    "A3" => "Area 3"
                )
            ),
            new TextField("FirstName", _t("General.FIRST_NAME", "First Name")),
            new TextField("Surname", _t("General.SURNAME", "Surname")),
            new DropdownField(
                "Gender",
                _t("General.GENDER", "Gender"),
                array(
                    "male" => _t("General.MALE", "Male"),
                    "female" => _t("General.FEMALE", "Female")
                )
            ),
            new TextField("ContactNumber", _t("General.CONTACT_NUMBER", "Contact Number")),
            $image,
            new PhpCaptchaField("CapchaCode")
        );

        $actions = new FieldList(new FormAction("DoRegistration", _t("General.SUBMIT", "Submit")));
        $validator = new RequiredFields("Username", "Password", "ConfirmPassword", "Email", "UnitNo", "AreaName", "FirstName", "Surname", "Gender", "ContactNumber", "SnPUpload", "CapchaCode");

        return new Form($this, "RegistrationForm", $fields, $actions, $validator);
    }

    public function DoRegistration($data, $form)
    {
        $hasError = false;

        $arr = array(
            "Username" => _t("RegistrationPage.USERNAME_DESC", "Username length must be 6-18 characters."),
            "Password" => _t("RegistrationPage.PASSWORD_DESC", "Password length must be 6-18 characters.")
        );

        // Check value length.
        foreach ($arr as $name => $desc) {
            if (strlen($data[$name]) < 6 || strlen($data[$name]) > 18) {
                $form->addErrorMessage($name, $desc, Globals::STATUS_BAD);
                $hasError = true;
            }
        }

        // Check confirm password.
        if ($data["Password"] !== $data["ConfirmPassword"]) {
            $form->addErrorMessage("ConfirmPassword", _t("General.PASSWORD_NOT_MATCH", "Password is not match."), Globals::STATUS_BAD);
            $hasError = true;
        }

        if (!$hasError) {
            // Check for duplication.
            $exists = Resident::get()->filterAny(
                array(
                    "Username" => $data["Username"],
                    "UnitNo" => $data["UnitNo"],
                    "AreaName" => $data["AreaName"]
                )
            );

            foreach ($exists as $row) {
                if ($row->Username == $data["Username"]) {
                    $form->addErrorMessage("Username", _t("General.USERNAME_ALREADY_IN_USE", "Username already used by others."), Globals::STATUS_BAD);
                    $hasError = true;
                }
                if ($row->UnitNo == $data["UnitNo"] && $row->AreaName == $data["AreaName"]) {
                    $form->addErrorMessage("UnitNo", _t("General.UNIT_ALREADY_REGISTERED", "This unit is already registered."), Globals::STATUS_BAD);
                    $hasError = true;
                }
                if ($hasError) {
                    break;
                }
            }
        }

        if ($hasError) {
            // $data["Password"] = $data["ConfirmPassword"] = ""; // Remove password fields.
            Session::set("FormInfo.Form_RegistrationForm.data", $data); // Retain form data for correction.
            return $this->redirectBack();
        }

        $model = new Resident();
        $form->saveInto($model);

        $model->AccountStatus = Globals::STATUS_PENDING;

        if ($model->write() > 0) {
            // Success. Assign group and show flash message.
            $mem = Member::get()->byID($model->ID);
            $mem->addToGroupByCode("resident", "Resident");

            $this->setFlashMessage(_t("RegistrationPage.REGISTER_SUCCESS_FLASH", "Account registered successfully. Please wait for our admin to approve your application. Thank you."), Globals::STATUS_SUCCESS);
        } else {
            // Failed.
            $this->setFlashMessage(_t("RegistrationPage.REGISTER_FAIL_FLASH", "Unable to register new account. Please try again later."), Globals::STATUS_ERROR);
        }

        return $this->redirectBack();
    }
}